<?php

namespace App\Controller\Api\Consultant;

use App\Algorithm\ScheduleAlgorithm;
use App\Constants\ErrorCode;
use App\Controller\Api\BaseController;
use App\Model\ConfusionCategory;
use App\Model\Language;
use App\Model\OrderReservation;
use App\Model\UserDatum;
use App\Model\WorkDate;
use App\Model\WorkReservation;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use App\Middleware\JWTAuthConsultantMiddleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Psr\Http\Message\ResponseInterface;

/**
 * @Middleware(JWTAuthConsultantMiddleware::class)
 * @Controller(prefix="/consultant/v1/work")
 */
class WorkController extends BaseController
{


    /**
     * @Inject()
     * @var ScheduleAlgorithm
     */
    public $scheduleAlgorithm;


    /**
     * @RequestMapping(path="scheduling")
     * @return ResponseInterface
     */
    public function scheduling()
    {

        $wid = $this->request->query('wid');
        if (empty($wid)) {
            $workDay = strtotime(date('Y-m-d', time()));
            $workDateInfo = WorkDate::where(['work_day' => $workDay])->first();

        } else {
            $workDateInfo = WorkDate::where(['id' => $wid])->first();
        }


        if (is_null($workDateInfo)) {
            return $this->response->returnFail(ErrorCode::WORK_DATE_NOT);
        }

        if ($workDateInfo['start'] < time()) {
            $workDateInfo['start'] = time();
        }


        $occupiedTimeSlots = WorkReservation::where(['wid' => $workDateInfo['id']])->orderBy('start')->get()->toArray();


        $list = $this->scheduleAlgorithm->scheduling($workDateInfo['start'], $workDateInfo['end'], $occupiedTimeSlots);

        foreach ($list as $k => $v) {
            $list[$k]['type'] = 3;
            $list[$k]['status'] = 4;
            $list[$k]['wid'] = $workDateInfo['id'];
            $list[$k]['uid'] = $workDateInfo['uid'];
        }
        $list = array_merge($list, $occupiedTimeSlots);

        array_multisort(array_column($list, 'start'), SORT_ASC, $list);


        return $this->response->returnSuccess(['list' => $list]);


    }


    /**
     * @RequestMapping(path="scheduleList")
     * @return ResponseInterface
     */
    public function scheduleList()
    {

        $today = strtotime(date('Y-m-d', time()));

        $scheduleArr = [];
        $scheduleKeyArr = [];

        $nextDay = $today;
        for ($i = 0; $i < 7; $i++) {
            $scheduleArr[] = $nextDay;
            $scheduleKeyArr[$nextDay] = null;
            $nextDay += 86400;
        }

        $workDateList = WorkDate::whereIn('work_day', $scheduleArr)->where(['uid'=>$this->uid()])->get()->toArray();


        foreach ($workDateList as $k => $v) {
            $scheduleKeyArr[$v['work_day']] = $v;
        }

        ksort($scheduleKeyArr);

        $list = [];
        foreach ($scheduleKeyArr as $k => $v) {
            $list[] = [
                'workDay' => $k,
                'info' => $v
            ];

        }


        return $this->response->returnSuccess(['list' => $list]);


    }


    /**
     * 设置排班时间
     * @RequestMapping(path="setWorkingHours")
     * @return ResponseInterface
     */
    public function setWorkingHours()
    {

        $params = $this->request->post();

        $this->validate($params, [
            'workDay' => 'required',
            'start' => 'required',
            'end' => 'required'
        ]);

        $today = strtotime(date('Y-m-d', time()));

        if ($today > $params['workDay']) {
            return $this->response->returnFail(ErrorCode::WORK_BEFORE);
        }


        $workDateExists = WorkDate::where(['work_day' => $params['workDay']])->exists();

        if ($workDateExists) {
            return $this->response->returnFail(ErrorCode::WORK_ALREADY);
        }

        $insertData = [
            'uid' => $this->uid(),
            'work_day' => $params['workDay'],
            'start' => $params['start'],
            'end' => $params['end'],
            'status' => 1,
            'create_time' => time(),
        ];

        $id = WorkDate::insertGetId($insertData);
        if ($id) {

            $insertData['id'] = $id;

            return $this->response->returnSuccess(['info' => $insertData]);
        } else {
            return $this->response->returnFail();
        }


    }


    /**
     * @RequestMapping(path="removeWorkingHours")
     * @return ResponseInterface
     */
    public function removeWorkingHours()
    {
        $params = $this->request->post();

        $this->validate($params, [
            'wid' => 'required',
            'start' => 'required',
            'end' => 'required'
        ]);

        $workDayInfo = WorkDate::where(['id' => $params['wid']])->first();

        if (is_null($workDayInfo)) {
            return $this->response->returnFail(ErrorCode::WORK_DATE_NOT);
        }
        //判断是否在允许的休息时间内

        // 你的大时间区间
        $rangeStart = $workDayInfo['start'];

        if ($rangeStart < time()) {
            $rangeStart = time();
        }

        $rangeEnd = $workDayInfo['end'];

        if ($rangeStart >= $rangeEnd) {
            return $this->response->returnFail(ErrorCode::WORK_TIME_FAIL);
        }

        // 已被占用的时间段
        $where[] = ['wid', '=', $workDayInfo['id']];
        $where[] = ['end', '>', time()];

        $occupiedTimeSlots = WorkReservation::where($where)->orderBy('start')->get()->toArray();

        // 你希望选择的小区间
        $desiredStart = $params['start'];
        $desiredEnd = $params['end'];

        if ($desiredStart >= $desiredEnd) {
            return $this->response->returnFail(ErrorCode::WORK_TIME_FAIL);
        }

        $rel = $this->scheduleAlgorithm->isTimeSlotAvailable($rangeStart, $rangeEnd, $occupiedTimeSlots, $desiredStart, $desiredEnd);

        if ($rel) {
            $insertData = [
                'uid' => $this->uid(),
                'wid' => $params['wid'],
                'start' => $desiredStart,
                'end' => $desiredEnd,
                'type' => 2,
                'status' => 3,
                'create_time' => time()
            ];

            $res = WorkReservation::insert($insertData);

            if ($res) {
                return $this->response->returnSuccess();
            } else {
                return $this->response->returnFail();
            }


        } else {
            return $this->response->returnFail(ErrorCode::WORK_TIME_FAIL);
        }


    }


    /**
     * @RequestMapping(path="removeRest")
     * @return ResponseInterface
     * @throws \Exception
     */
    public function removeRest()
    {
        $id = $this->request->post('id');
        if (empty($id)) {
            return $this->response->returnFail();
        }

        //todo  后面加上时间限制
        $info = WorkReservation::where(['id' => $id, 'uid' => $this->uid(),'status'=>3])->first();

        if (is_null($info)) {
            return $this->response->returnFail();
        }

        $rel = $info->delete();

        if ($rel) {
            return $this->response->returnSuccess();
        } else {
            return $this->response->returnFail();
        }


    }


    /**
     * @RequestMapping(path="workingHoursDetails")
     * @return ResponseInterface
     */
    public function workingHoursDetails()
    {

        $id = $this->request->query('id');

        $workHourInfo = WorkReservation::where(['id' => $id])->first();

        if (is_null($workHourInfo)) {
            return $this->response->returnFail();
        }


        $orderReservation = OrderReservation::where(['tid' => $id])->first();
        if (is_null($orderReservation)) {
            return $this->response->returnFail();
        }

        $userInfo = UserDatum::from('user_datum as a')
            ->leftJoin('user as b', 'a.uid', '=', 'b.id')
            ->where(['a.uid' => $orderReservation['uid']])
            ->select(['a.head', 'a.language', 'a.confusion_id as confusionId', 'a.nickname', 'b.num', 'a.uid'])
            ->first();


        if (is_null($userInfo)) {
            return $this->response->returnFail();
        }

        $workHourInfo = $workHourInfo->toArray();

        $userInfo = $userInfo->toArray();

        if ($userInfo['confusionId']) {
            $userInfo['confusion'] = ConfusionCategory::whereIn('id', explode(',', $userInfo['confusionId']))->pluck('name');
        } else {
            $userInfo['confusion'] = null;
        }

        if ($userInfo['language']) {
            $userInfo['language'] = Language::where(['id' => $userInfo['language']])->value('name');
        }


        $workHourInfo['userInfo'] = $userInfo;

        return $this->response->returnSuccess(['info' => $workHourInfo]);


    }


}